package com.autonavi.yunda.yunji.core.utils;

import com.autonavi.yunda.yunji.common.exception.AmapException;
import com.autonavi.yunda.yunji.common.exception.AmapExceptionCode;
import com.autonavi.yunda.yunji.common.exception.AmapPreconditions;
import com.autonavi.yunda.yunji.common.utils.SpringUtil;
import com.autonavi.yunda.yunji.core.service.IDynamicConfigService;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * @author cizhong.wcs
 * @date 2022/9/5 17:00
 */
public class DynamicConfigUtil {
    private static final Cache<String, String> cache = CacheBuilder.newBuilder()
            //设置并发级别为8，并发级别是指可以同时写缓存的线程数
            .concurrencyLevel(8)
            //设置缓存容器的初始容量为10
            .initialCapacity(10)
            //设置缓存最大容量为5000 超过5000之后就会按照LRU最近虽少使用算法来移除缓存项
            .maximumSize(5000)
            //设置写缓存后n秒钟过期
            .expireAfterWrite(30, TimeUnit.SECONDS)
            .build();


    /**
     * what： 从缓存中获取动态变量
     * how：
     *  1. 先从缓存中获取
     *  2. 缓存不存在，再从yunji_dynamic_config表中获取
     * @param projectId
     * @param key
     * @return
     */
    public static String getString(String projectId, String key) {
        AmapPreconditions.checkNotNull(projectId);
        try {
            return cache.get(projectId + key, () -> {
                //
                IDynamicConfigService service = SpringUtil.getBean(IDynamicConfigService.class);
                String result = service.fetchValue(projectId, key);
                if (result == null) {
                    throw new AmapException(AmapExceptionCode.COMMON_ILLEGAL_PARAM, "配置为空 key =" + key + ", projectId =" + projectId);
                }
                return result;
            });
        } catch (ExecutionException e) {
            throw new AmapException(AmapExceptionCode.COMMON_SERVER_ERROR, "配置获取异常", e);
        }
    }
}
